<?php
namespace Api\Service;

/**
 * 订单
 */
class OrderService
{
    const UN_PAY        = 1; // 未付款
    const PAYED         = 2; // 已付款，待发货
    const RECEIPT       = 3; // 待确认收货
    const FINISH        = 4; // 已完成，待评论
    const REVIEW        = 5; // 已评论
    const REFUND        = 11; // 申请退货/退款中
    const REFUND_FINISH = 12; // 退款处理完成

    const ORDER_DEFAULT = 1; // 普通订单

    // 订单分页大小
    const PAGET_NUMBER = 10;

    /**
     * 订单状态字典
     * @return [type] [description]
     */
    public function status($code = 0)
    {
        $status = [
            self::UN_PAY        => '未付款',
            self::PAYED         => '待发货',
            self::RECEIPT       => '待收货',
            self::FINISH        => '已完成',
            self::REVIEW        => '已评论',
            self::REFUND        => '退货/退款中',
            self::REFUND_FINISH => '退款处理完成',
        ];

        if ($code) {
            return $status[$code];
        }

        return $status;
    }

    /**
     * 生成订单
     * @param  [type] $user_id    [description]
     * @param  [type] $cart       [description]
     * @param  [type] $address_id [description]
     * @param  [type] $coupon_id  [description]
     * @return [type]             [description]
     */
    public function create($user_id, $cart, $address_id, $coupon_id)
    {
        // 商品的所有店铺+所有商品+所有规格
        $shop_ids      = [];
        $spec_item_ids = [];
        foreach ($cart as $key => $val) {
            $shop_ids[]      = $val['shop_id'];
            $spec_item_ids[] = $val['spec_item_id'];
            $goods_ids[]     = $val['goods_id'];
        }
        // 去重
        $shop_ids      = array_unique($shop_ids);
        $goods_ids     = array_unique($goods_ids);
        $spec_item_ids = array_unique($spec_item_ids);

        // 门店
        $shops = M('shop')
            ->where([
                'id'      => ['in', $shop_ids],
                'is_open' => 1,
            ])->getField('id,logo,name', true);

        // 商品
        $goodss = M('goods')
            ->where([
                'id'        => ['in', $goods_ids],
                'is_sales'  => 1,
                'stock'     => ['gt', 0],
                'is_delete' => 0,
            ])->getField('id,title,image,price,express_fee', true);

        // 规格属性
        $spec_items = M('goods_spec_item')
            ->where([
                'id'       => ['in', $spec_item_ids],
                'is_sales' => 1,
                'stock'    => ['gt', 0],
            ])->getField('id,goods_id,name,price,express_fee', true);

        // 用户收获地址
        $address = M('address')
            ->where([
                'id'      => $address_id,
                'user_id' => $user_id,
            ])->find();
        if (!$address) {
            return false;
        }

        $mobile   = $address['mobile'];
        $username = $address['name'];
        $address  = $address['province'] . $address['city'] . $address['region'] . $address['address'];

        // 先生成总订单，再更新信息
        // 再生成门店订单，父订单支付完成，子订单支付完成
        $parent_order_id = $this->generateParentOrder($user_id);
        if (!$parent_order_id) {
            return false;
        }

        $orders = [];
        foreach ($cart as $key => $val) {
            $order = &$orders[$val['shop_id']];

            $order['shop_id']   = $val['shop_id'];
            $order['user_id']   = $user_id;
            $order['parent_id'] = $parent_order_id;
            $order['order_no']  = generate_order_no($user_id);

            $order['name']    = $username;
            $order['mobile']  = $mobile;
            $order['address'] = $address;

            $order['type']     = self::ORDER_DEFAULT;
            $order['is_pay']   = 0;
            $order['pay_time'] = '';
            $order['status']   = self::UN_PAY;
            $order['add_time'] = CUR_DATETIME;

            $price = 0;
            if ($val['spec_item_id']) {

                $price       = $spec_items[$val['spec_item_id']]['price'];
                $express_fee = $spec_items[$val['spec_item_id']]['express_fee'];

                $spec_item_id = $val['spec_item_id'];
            } else {

                $price       = $goodss[$val['goods_id']]['price'];
                $express_fee = $goodss[$val['goods_id']]['express_fee'];

                $spec_item_id = 0;
            }
            $order['express_fee'] += $express_fee;
            $order['total'] += $price + $express_fee;

            $order['goods'][] = [
                'goods_id'     => $val['goods_id'],
                'spec_item_id' => $spec_item_id,
                'price'        => $price,
                'number'       => $val['number'],
                'goods_name'   => $goodss[$val['goods_id']]['title'] . ' ' . $spec_items[$val['spec_item_id']]['name'],
                'goods_image'  => $goodss[$val['goods_id']]['image'],
            ];
        }

        // 数据库相关
        $total       = 0;
        $express_fee = 0;
        foreach ($orders as $key => $order) {
            $total += $order['total'];
            $express_fee += $order['express_fee'];

            $tmp_goods = $order['goods'];
            unset($orders[$key]['goods']);

            // 插入店铺订单
            $order_id = M('order')->add($order);

            foreach ($tmp_goods as $k => $goods) {
                $tmp_goods[$k]['order_id'] = $order_id;
                $tmp_goods[$k]['add_time'] = CUR_DATETIME;
            }

            // 插入订单商品
            $res1 = M('order_goods')->addAll($tmp_goods);
        }

        // 更新父订单
        $res2 = M('order')
            ->where([
                'id' => $parent_order_id,
            ])->save([
            'total'       => $total,
            'express_fee' => $express_fee,
        ]);

        return $res1 && $res2 ? $parent_order_id : false;
    }

    /**
     * [search description]
     * @return [type] [description]
     */
    public function search($user_id, $type, $page = 1)
    {
        $where = [
            'user_id'   => $user_id,
            'parent_id' => ['neq', 0],
        ];
        if ($type) {
            $where['status'] = $type;
        }

        $count      = M('order')->where($where)->count();
        $total_page = intval($count / self::PAGET_NUMBER);
        $orders     = M('order')
            ->field('id,shop_id,order_no,type,total,express_fee,status,add_time')
            ->where($where)
            ->page($page, self::PAGET_NUMBER)
            ->order('id desc')
            ->select();

        foreach ($orders as $k => $order) {
            $orders[$k]['status_str'] = $this->status($order['status']);
            $orders[$k]['goods']      = $this->goods($order['id']);
            unset($orders[$k]['id']);
        }

        return [
            'count'    => intval($count),
            'cur_page' => intval($page),
            'page'     => $total_page ? $total_page : 0,
            'data'     => $orders ? $orders : [],
        ];
    }

    /**
     * 订单详情
     * @param  [type] $user_id  [description]
     * @param  [type] $order_no [description]
     * @return [type]           [description]
     */
    public function detail($user_id, $order_no)
    {
        $order = M('order')->alias('o')
            ->field('o.id,o.shop_id,s.name shop_name,s.logo shop_logo,o.order_no,o.total,o.name,o.mobile,o.address,o.express_fee,o.is_pay,o.pay_method,o.pay_time,o.is_delivery,o.status,o.express,o.express_no,o.add_time')
            ->join('__SHOP__ s on o.shop_id = s.id')
            ->where([
                'o.user_id'  => $user_id,
                'o.order_no' => $order_no,
            ])->find();
        if (!$order) {
            return [];
        }

        $order['status'] = $this->status($order['status']);
        $order['goods']  = $this->goods($order['id']);

        return $order ? $order : [];
    }

    /**
     * 生成父订单
     * @param  [type] $user_id [description]
     * @return [type]          [description]
     */
    protected function generateParentOrder($user_id)
    {
        $order_id = 0;
        do {
            $order = [
                'user_id'   => $user_id,
                'parent_id' => 0,
                'order_no'  => $order_no = generate_order_no($user_id),
                'type'      => self::ORDER_DEFAULT,
                'is_pay'    => 0,
                'pay_time'  => CUR_DATETIME,
                'status'    => self::UN_PAY,
                'add_time'  => CUR_DATETIME,
            ];
            $order_id = M('order')->add($order);
        } while (!$order_id);

        return $order_id;
    }

    /**
     * 获取订单的商品
     * @param  [type] $order_id [description]
     * @return [type]           [description]
     */
    public function goods($order_id)
    {
        $goods = S('order_goods_' . $order_id);
        if (!$goods || true) {
            $goods = M('order_goods')
                ->field('spec_item_id,goods_id,goods_name,goods_image,number,price,is_review,add_time')
                ->where([
                    'order_id' => $order_id,
                ])->select();

            foreach ($goods as $key => $val) {
                $goods[$key]['spec_item_str'] = D('Api/Goods', 'Service')->getSpecItemStr($val['spec_item_id']);
            }

            S('order_goods_' . $order_id, $goods);
        }

        return $goods;
    }

    /**
     * 物流信息
     * @param  [type] $order_no [description]
     * @return [type]           [description]
     */
    public function express($order_no)
    {
        $info = M('order')->alias('o')
            ->field('o.express,o.express_no')
            ->join('__EXPRESS__ e on o.express = e.com')
            ->where([
                'o.order_no' => $order_no,
            ])->find();

        if (!$info) {
            return [];
        }

        $info['list'] = D('Api/Express', 'Service')->traces($info['express'], $info['express_no']);

        return $info ? $info : [];
    }

    /**
     * 评论订单商品
     * @param  [type] $user_id      [description]
     * @param  [type] $order_no     [description]
     * @param  [type] $goods_id     [description]
     * @param  [type] $spec_item_id [description]
     * @param  [type] $review       [description]
     * @param  [type] $images       [description]
     * @return [type]               [description]
     */
    public function review($user_id, $order_no, $goods_id, $spec_item_id, $review, $images)
    {
        $order_id = M('order')->where(['order_no' => $order_no])->getField('id');

        // 是否已评论过
        $is_review = M('order_goods')
            ->where([
                'order_id'     => $order_id,
                'goods_id'     => $goods_id,
                'spec_item_id' => $spec_item_id,
            ])->count();

        if ($is_review) {
            return false;
        }

        // 正常流程
        $shop_id   = M('goods')->where(['id' => $goods_id])->getField('shop_id');
        $spec_item = D('Api/Goods', 'Service')->getSpecItemStr($spec_item_id);

        $review = [
            'shop_id'         => $shop_id,
            'user_id'         => $user_id,
            'goods_id'        => $goods_id,
            'spec_item'       => $spec_item,
            'content'         => $review['content'],
            'express_service' => $review['express_service'],
            'goods_match'     => $review['goods_match'],
            'shop_service'    => $review['shop_service'],
            'add_time'        => CUR_DATETIME,
        ];

        begin();
        $res1 = M('review')->add($review);

        $res2 = M('order_goods')
            ->where([
                'order_id'     => $order_id,
                'goods_id'     => $goods_id,
                'spec_item_id' => $spec_item_id,
            ])->save([
            'is_review'   => 1,
            'review_time' => CUR_DATETIME,
        ]);

        if (count($images)) {
            $review_image = [];
            foreach ($images as $image) {
                $review_image[] = [
                    'review_id' => $res1,
                    'image'     => $image,
                    'add_time'  => CUR_DATETIME,
                ];
            }
            M('review_image')->addAll($review_image);
        }

        if ($res1 && $res2) {
            commit();
            return true;
        } else {
            rollback();
            return false;
        }
    }
}
